#include "../include/ReportGenerator.hh"
#include <iostream>
#include <fstream>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <algorithm>

ReportGenerator::ReportGenerator() {
}

bool ReportGenerator::generateGlobalTransactionReport(const std::vector<Transaction>& transactions) const {
    std::string filename = generateFilename("transactions");
    
    // 在控制台显示报告内容
    std::cout << "\n======= 全局交易报告 =======" << std::endl;
    displayTransactionsOnConsole(transactions);
    
    return writeTransactionsToFile(filename, transactions);
}

bool ReportGenerator::generateCustomerReport(const std::string& customerName, 
                                            const std::vector<Transaction>& transactions) const {
    std::string filename = generateFilename("transactions_" + customerName);
    
    // 在控制台显示报告内容
    std::cout << "\n======= " << customerName << " 的交易报告 =======" << std::endl;
    displayTransactionsOnConsole(transactions);
    
    return writeTransactionsToFile(filename, transactions);
}

bool ReportGenerator::generateAccountReport(const std::string& accountId, 
                                           const std::vector<Transaction>& transactions) const {
    std::string filename = generateFilename("transactions_" + accountId);
    
    // 在控制台显示报告内容
    std::cout << "\n======= 账户 " << accountId << " 的交易报告 =======" << std::endl;
    displayTransactionsOnConsole(transactions);
    
    return writeTransactionsToFile(filename, transactions);
}

// 辅助方法：在控制台显示交易记录
void ReportGenerator::displayTransactionsOnConsole(const std::vector<Transaction>& transactions) const {
    if (transactions.empty()) {
        std::cout << "没有找到交易记录。" << std::endl;
        return;
    }

    std::cout << "总交易笔数: " << transactions.size() << std::endl << std::endl;
    
    // 计算统计数据
    double totalDeposits = 0.0;
    double totalWithdrawals = 0.0;
    double totalTransfers = 0.0;
    
    for (const auto& transaction : transactions) {
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                totalDeposits += transaction.amount;
                break;
            case TransactionType::WITHDRAW:
                totalWithdrawals += transaction.amount;
                break;
            case TransactionType::TRANSFER:
                totalTransfers += transaction.amount;
                break;
        }
    }
    
    // 显示统计信息
    std::cout << "交易统计:" << std::endl;
    std::cout << "- 总存款金额: ¥" << std::fixed << std::setprecision(2) << totalDeposits << std::endl;
    std::cout << "- 总取款金额: ¥" << std::fixed << std::setprecision(2) << totalWithdrawals << std::endl;
    std::cout << "- 总转账金额: ¥" << std::fixed << std::setprecision(2) << totalTransfers << std::endl;
    std::cout << "- 净存款: ¥" << std::fixed << std::setprecision(2) << (totalDeposits - totalWithdrawals) << std::endl;
    std::cout << std::endl;
    
    // 显示交易记录（限制显示的数量，避免控制台输出过多）
    int maxDisplayCount = std::min(static_cast<int>(transactions.size()), 10);
    std::cout << "最近 " << maxDisplayCount << " 条交易记录:" << std::endl;
    std::cout << "---------------------------------------------------" << std::endl;
    
    // 从最新的交易开始显示
    for (int i = 0; i < maxDisplayCount; ++i) {
        const auto& transaction = transactions[transactions.size() - 1 - i];
        transaction.display();
    }
    
    if (transactions.size() > maxDisplayCount) {
        std::cout << "... 更多交易记录已保存到文件中 ..." << std::endl;
    }
}

bool ReportGenerator::generateQuarterlyReport(int year, int quarter, 
                                             const std::vector<Transaction>& transactions) const {
    if (quarter < 1 || quarter > 4) {
        std::cout << "错误：季度必须为1到4之间的数字。" << std::endl;
        return false;
    }
    
    std::string filename = generateFilename("quarterly_report_" + std::to_string(year) + "_Q" + std::to_string(quarter));
    
    std::ofstream file(filename);
    if (!file.is_open()) {
        std::cout << "错误：无法创建报告文件 " << filename << std::endl;
        return false;
    }
    
    // 季度的开始和结束月份
    int startMonth = (quarter - 1) * 3 + 1;
    int endMonth = quarter * 3;
    
    // 筛选此季度的交易
    std::vector<Transaction> quarterlyTransactions;
    for (const auto& transaction : transactions) {
        time_t transactionTime = transaction.timestamp;
        std::tm* timeInfo = std::localtime(&transactionTime);
        
        // 检查是否是指定年份和季度
        if (timeInfo->tm_year + 1900 == year && 
            (timeInfo->tm_mon + 1) >= startMonth && 
            (timeInfo->tm_mon + 1) <= endMonth) {
            quarterlyTransactions.push_back(transaction);
        }
    }
    
    // 输出到控制台
    std::cout << "\n======= " << year << " 年第 " << quarter << " 季度银行交易报告 =======" << std::endl;
    std::cout << "覆盖时期: " << year << "-" << startMonth << "-01 至 " << year << "-" << endMonth << "-" 
         << (endMonth == 2 ? "28/29" : (endMonth == 4 || endMonth == 6 || endMonth == 9 || endMonth == 11 ? "30" : "31")) << std::endl;
    std::cout << std::endl;
    
    displayTransactionsOnConsole(quarterlyTransactions);
    
    // 写入报告头部
    file << "======= " << year << " 年第 " << quarter << " 季度银行交易报告 =======" << std::endl;
    
    time_t now = std::time(nullptr);
    file << "生成时间: " << std::put_time(std::localtime(&now), "%Y-%m-%d %H:%M:%S") << std::endl;
    
    file << "覆盖时期: " << year << "-" << startMonth << "-01 至 " << year << "-" << endMonth << "-" 
         << (endMonth == 2 ? "28/29" : (endMonth == 4 || endMonth == 6 || endMonth == 9 || endMonth == 11 ? "30" : "31")) << std::endl;
    file << std::endl;
    
    // 交易统计
    double totalDeposits = 0.0;
    double totalWithdrawals = 0.0;
    double totalTransfers = 0.0;
    
    for (const auto& transaction : quarterlyTransactions) {
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                totalDeposits += transaction.amount;
                break;
            case TransactionType::WITHDRAW:
                totalWithdrawals += transaction.amount;
                break;
            case TransactionType::TRANSFER:
                totalTransfers += transaction.amount;
                break;
        }
    }
    
    // 写入统计信息
    file << "交易统计:" << std::endl;
    file << "- 总交易笔数: " << quarterlyTransactions.size() << std::endl;
    file << "- 总存款金额: ¥" << std::fixed << std::setprecision(2) << totalDeposits << std::endl;
    file << "- 总取款金额: ¥" << std::fixed << std::setprecision(2) << totalWithdrawals << std::endl;
    file << "- 总转账金额: ¥" << std::fixed << std::setprecision(2) << totalTransfers << std::endl;
    file << "- 净存款: ¥" << std::fixed << std::setprecision(2) << (totalDeposits - totalWithdrawals) << std::endl;
    file << std::endl;
    
    // 写入详细的交易记录
    file << "详细交易记录:" << std::endl;
    file << "---------------------------------------------------" << std::endl;
    
    for (const auto& transaction : quarterlyTransactions) {
        file << "交易ID: " << transaction.transactionId << std::endl;
        
        // 显示交易类型
        file << "类型: ";
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                file << "存款";
                break;
            case TransactionType::WITHDRAW:
                file << "取款";
                break;
            case TransactionType::TRANSFER:
                file << "转账";
                break;
        }
        file << std::endl;
        
        file << "金额: ¥" << std::fixed << std::setprecision(2) << transaction.amount << std::endl;
        
        // 格式化时间
        std::tm* timeInfo = std::localtime(&transaction.timestamp);
        file << "时间: " << std::put_time(timeInfo, "%Y-%m-%d %H:%M:%S") << std::endl;
        
        // 根据交易类型显示适当的账户信息
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                file << "存入账户: " << transaction.destinationAccountId << std::endl;
                break;
            case TransactionType::WITHDRAW:
                file << "从账户: " << transaction.sourceAccountId << std::endl;
                break;
            case TransactionType::TRANSFER:
                file << "从账户: " << transaction.sourceAccountId << std::endl;
                file << "到账户: " << transaction.destinationAccountId << std::endl;
                break;
        }
        
        // 显示备注（如果有）
        if (!transaction.note.empty()) {
            file << "备注: " << transaction.note << std::endl;
        }
        
        file << "---------------------------------------------------" << std::endl;
    }
    
    file.close();
    
    std::cout << "季度报告已成功生成: " << filename << std::endl;
    return true;
}

bool ReportGenerator::generateAuditReport(const std::string& startDate, const std::string& endDate, 
                                         const std::vector<Transaction>& transactions) const {
    std::string filename = generateFilename("audit_report_" + startDate + "_to_" + endDate);
    
    // 在控制台显示
    std::cout << "\n======= 审计报告 (" << startDate << " 至 " << endDate << ") =======" << std::endl;
    std::cout << "注意：此为简化版本，展示所有交易记录" << std::endl << std::endl;
    
    displayTransactionsOnConsole(transactions);
    
    // 这里应该有日期解析和按日期筛选交易的逻辑
    // 简化版本，直接使用所有交易记录
    
    return writeTransactionsToFile(filename, transactions);
}

bool ReportGenerator::writeTransactionsToFile(const std::string& filename, 
                                             const std::vector<Transaction>& transactions) const {
    std::ofstream file(filename);
    if (!file.is_open()) {
        std::cout << "错误：无法创建报告文件 " << filename << std::endl;
        return false;
    }
    
    file << "======= 交易报告 =======" << std::endl;
    
    time_t now = std::time(nullptr);
    file << "生成时间: " << std::put_time(std::localtime(&now), "%Y-%m-%d %H:%M:%S") << std::endl;
    
    file << "总交易笔数: " << transactions.size() << std::endl;
    file << std::endl;
    
    for (const auto& transaction : transactions) {
        file << "交易ID: " << transaction.transactionId << std::endl;
        
        // 显示交易类型
        file << "类型: ";
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                file << "存款";
                break;
            case TransactionType::WITHDRAW:
                file << "取款";
                break;
            case TransactionType::TRANSFER:
                file << "转账";
                break;
        }
        file << std::endl;
        
        file << "金额: ¥" << std::fixed << std::setprecision(2) << transaction.amount << std::endl;
        
        // 格式化时间
        std::tm* timeInfo = std::localtime(&transaction.timestamp);
        file << "时间: " << std::put_time(timeInfo, "%Y-%m-%d %H:%M:%S") << std::endl;
        
        // 根据交易类型显示适当的账户信息
        switch (transaction.type) {
            case TransactionType::DEPOSIT:
                file << "存入账户: " << transaction.destinationAccountId << std::endl;
                break;
            case TransactionType::WITHDRAW:
                file << "从账户: " << transaction.sourceAccountId << std::endl;
                break;
            case TransactionType::TRANSFER:
                file << "从账户: " << transaction.sourceAccountId << std::endl;
                file << "到账户: " << transaction.destinationAccountId << std::endl;
                break;
        }
        
        // 显示备注（如果有）
        if (!transaction.note.empty()) {
            file << "备注: " << transaction.note << std::endl;
        }
        
        file << "---------------------------------------------------" << std::endl;
    }
    
    file.close();
    
    std::cout << "报告已成功生成: " << filename << std::endl;
    return true;
}

std::string ReportGenerator::generateFilename(const std::string& prefix) const {
    // 获取当前日期
    auto now = std::chrono::system_clock::now();
    auto time = std::chrono::system_clock::to_time_t(now);
    std::tm* timeInfo = std::localtime(&time);
    
    std::stringstream ss;
    ss << prefix << "_"
       << (timeInfo->tm_year + 1900) << "-"
       << std::setw(2) << std::setfill('0') << (timeInfo->tm_mon + 1) << "-"
       << std::setw(2) << std::setfill('0') << timeInfo->tm_mday
       << ".txt";
    
    return ss.str();
} 